import { BaseComponent } from './../../components/baseComponent';
import { TimeManager } from './../../common/timeManager';
import { ShellIntegrationService } from './../../services/shellIntegration';
import { ViewChild, ChangeDetectorRef, ElementRef, AfterViewInit, ChangeDetectionStrategy, style, Input } from '@angular/core';
import { PagingMessage, YScrollableContainer } from './../../components/scrollable/y-scrollable-container';
import { FNCManager, KdsMessageType } from './../../common/fnc/fncManager';
import { PlayAudioService } from './../../components/app-components/play-audio';
import { GrowlMessageType } from './../../components/messageBox/growMeaageType';
import { LocalstorageDataManage } from './../../common/localstoreage/localstoreageDataManage';
import { EmployeeInfosManage, EmployeInfoStatus } from './../../services/employeesInfoManage';
import { Employee } from './../../models/Employee';
import { ExpeditionOrder } from './../../models/expeditionOrder';
import { employeesService } from './../../services/employee';
import { expeditionOrdersService } from './../../services/expeditionOrders';
import { Observable, Subject, Subscription } from 'rxjs';
import { Component, OnInit, OnDestroy, ViewChildren, QueryList } from '@angular/core';
import { MessageBoxService } from "../../components/messageBox/messageBoxService";
import { delay } from "rxjs/operator/delay";
import * as R from "ramda";
import { Debounce, HandleExpectionErrorUseGrowMessage, OperationLock } from "../../common/decorator/index";

@Component({
  selector: 'home',
  templateUrl: './home.component.html',
  providers: [

  ],
  styleUrls: ['./home.component.scss'],
   changeDetection: ChangeDetectionStrategy.OnPush
})
export class HomeComponent extends BaseComponent implements OnInit, AfterViewInit, OnDestroy {
  @ViewChildren(YScrollableContainer)
  private yScrollableContainers: QueryList<YScrollableContainer>;
  private orderList: Array<ExpeditionOrder> = [];
  private employeeList:Array<Employee>;
  private matchedDeliveryer: MatchDeliveryer = <any>{};
  private liWidth;
  private deliverStyle: {};
  private nextCount;
  private previousCount;

  private selectOrders$ = new Subject<Array<ExpeditionOrder>>()
  private multipleOrders$ = this.selectOrders$.map(orders=>orders&&orders.length>1).share();
  constructor(
    private element: ElementRef, private shellIntegrationService: ShellIntegrationService,private changeDetectorRef: ChangeDetectorRef, private el: ElementRef
  ) {
    super();
  }

  @Debounce(500)
  yScrollableContainerChildrenChanged(){
      this.yScrollableContainers.first.childrenChanged();
  }


  public async ngOnInit() {
    
    const notExpeditionOrders$ = expeditionOrdersService.getNotExpeditionOrders();
    const subscription = notExpeditionOrders$.subscribe(orders => {
      this.orderList = orders.sort((a, b) => a.expediteBeginTime - b.expediteBeginTime);
      this.yScrollableContainerChildrenChanged();
      // const matchedOrderId = this.matchedDeliveryer.order && this.matchedDeliveryer.order.id;
      // if (this.orderList.findIndex(order => order.id == matchedOrderId) == -1) {
      //   this.matchedDeliveryer.order = this.orderList && this.orderList[0];
      // }
    })
    this.subscriptions.push(subscription);
    expeditionOrdersService.notify();

    const timer$ = Observable.interval(20000).share();
    const orderConfig = LocalstorageDataManage.current.getOrderConfig();
    const timeout = orderConfig.timeoutTiming * 60 * 1000;
    const setOrderTimeoutClass = R.partialRight(this.calcTimeout, [timeout]);
    this.subscriptions.push(timer$.subscribe(index=>{
       this.orderList = setOrderTimeoutClass(this.orderList);
       this.yScrollableContainerChildrenChanged();
    }))

    EmployeeInfosManage.current.init(LocalstorageDataManage.current.getEmployeeInfos())

    const employeeInfosManage$ = EmployeeInfosManage.current.getObservable();
    const employees = await employeesService.getDishesDistributor();
    const employeeSubscription = employeeInfosManage$.
      subscribe(employeeInfos => {
        if (!employeeInfos || employeeInfos.length == 0) return;
        employees && employees.forEach(employee => {
          const employeeInfo = employeeInfos.find(employeeInfo => employeeInfo.id == employee.id);
          employee.hasDeliveriedCount = employeeInfo.hasDeliveryCount || 0;
          employee.status = employeeInfo.status;
        })
        const onlineEmployees = employees.filter(x => x.status == EmployeInfoStatus.online);
        this.employeeList = onlineEmployees && onlineEmployees.sort((a, b) => a.user.name.localeCompare(b.user.name));
        this.changeDetectorRef.markForCheck();
        this.changeDetectorRef.detectChanges();
        this.dynamicWidth();
    })
    this.subscriptions.push(employeeSubscription);
  }
  ngOnDestroy() {
    this.shellIntegrationService.onCardreaderData = null;
    this.shellIntegrationService.onScanData = null;
    super.ngOnDestroy();
  }

  choosedOrders:Array<ExpeditionOrder> = [];
  renderOrder
  chooseDish(target:ExpeditionOrder | {serialNo:string}) {
    const serialNo = target.serialNo;
    const order = this.orderList.find(x=>x.serialNo == serialNo);
    if(!order ) {
        MessageBoxService.current.Growl(GrowlMessageType.Error,"没有该传菜单");
        return;
    }
    const index = this.choosedOrders.findIndex(x=>x.id == order.id);
    if(index>-1 && (<any>target).id ){
        const elelment = this.element.nativeElement.querySelector(`div[data-seriano='${this.choosedOrders[index].serialNo}']`);
        elelment && elelment.classList.remove("active");
        this.choosedOrders.splice(index , 1);
    } else if(index == -1){
        const elelment = this.element.nativeElement.querySelector(`div[data-seriano='${order.serialNo}']`);
        elelment && elelment.classList.add("active");
        this.choosedOrders.unshift(order);
    }
    // this.renderOrder(this.matchedDeliveryer.order );
    // requestAnimationFrame(() => {
    //     this.completeDeliver();
    // });

    this.selectOrders$.next(this.choosedOrders)
  }
  
  renderEmployee
  chooseDeliver(target:  {extended:{braceletNo:string}} | Employee):boolean {
    if((<any>target).id){
        this.matchedDeliveryer.employee = (<any>target);
    } else {
        const braceletNo = target.extended&&target.extended.braceletNo;
        this.matchedDeliveryer.employee = this.employeeList.find(x=>x.extended&&x.extended.braceletNo == braceletNo);
    }
    if(!this.matchedDeliveryer.employee) return false;
    this.renderEmployee(this.matchedDeliveryer.employee);
    // requestAnimationFrame(()=>{
    //     this.completeDeliver();
    // })
    return true;
  }

  calcTimeout(orderList, timeout){
    orderList ||( orderList = [])
      // const isOpenSound = orderConfig.isOpenTimeoutSound;
      orderList.filter(order => !order.timeoutClass && (TimeManager.current.getServerTime() - order.expediteBeginTime) > timeout).forEach(order => {
        order.timeoutClass = 'timeout';
        // if(isOpenSound){
        //   PlayAudioService.current.playAudio();
        // }
      });
      return orderList;
  }

  @HandleExpectionErrorUseGrowMessage()
  @OperationLock()
  async deliverExpeditionOrder() {
    if (!this.choosedOrders.length) {
      MessageBoxService.current.Growl(GrowlMessageType.Error, "没有待传菜");
      return false;
    }
    if (!this.matchedDeliveryer.employee || !this.matchedDeliveryer.employee.user.name) {
      MessageBoxService.current.Growl(GrowlMessageType.Error, "请选择传菜员");
      return false;
    }
    const deliveryer = {
      id: this.matchedDeliveryer.employee.id,
      name: this.matchedDeliveryer.employee.user.name
    }
   const result = await expeditionOrdersService.deliverBatchExpeditionOrder(this.choosedOrders.map(order=>order.id), deliveryer);
   this.toggleDeliverySuccessed();
   requestAnimationFrame(()=>{
      result.orders.forEach(order=>{
          FNCManager.Current.kdsMessageNotify(KdsMessageType.OrderMessage, order);
      })
      setTimeout(() => {
          this.toggleDeliverySuccessed();
          this.completeDeliver();
      }, 1000);
   })

  }

  private completeDeliver() {
    this.choosedOrders = [];
    this.selectOrders$.next(this.choosedOrders);
    this.matchedDeliveryer.employee = null;
    this.renderEmployee(this.matchedDeliveryer.employee);
  }

  pagingInfo: PagingMessage
  pagingMessageChange(event) {
    console.log("2222", event)
    this.pagingInfo = event;
    this.nextCount = this.pagingInfo.nextCount;
    this.previousCount = this.pagingInfo.previousCount;
  }

  ordersPagingInfo: PagingMessage = <any>{}
  ordersPagingMessageChange(event) {
    console.log("2222", event)
    this.ordersPagingInfo = event;
  }

  toggleDeliverySuccessed
  ngAfterViewInit() {
    const self = this;
    //扫小票二维码
    (<any>window).onScanData = (data) => {
      // const elelment = self.element.nativeElement.querySelector(`deliver-list[data-seriano='${data}']`);
      // elelment && elelment.click();
      this.chooseDish({serialNo:data})
    }
    this.shellIntegrationService.onScanData = (data) => {
      // const elelment = self.element.nativeElement.querySelector(`deliver-list[data-seriano='${data}']`);
      // elelment && elelment.click();
      this.chooseDish({serialNo:data})
    }

    //手环读卡
    (<any>window).onCardreaderData = (data) => {
      // const elelment = self.element.nativeElement.querySelector(`deliver[data-braceletNo='${data}']`);
      // if (elelment) {
      //   elelment.click();
      //   const deliveryDom = self.element.nativeElement.querySelector("#J_delivery");
      //   deliveryDom && deliveryDom.click();
      // }
        this.chooseDeliver({extended:{braceletNo:data}});
        requestAnimationFrame(this.deliverExpeditionOrder.bind(this));
    }
    this.shellIntegrationService.onCardreaderData = (data) => {
      // const elelment = self.element.nativeElement.querySelector(`deliver[data-braceletNo='${data}']`);
      // if (elelment) {
      //   elelment.click();
      //   const deliveryDom = self.element.nativeElement.querySelector("#J_delivery");
      //   deliveryDom && deliveryDom.click();
      // }
        this.chooseDeliver({extended:{braceletNo:data}});
        requestAnimationFrame(this.deliverExpeditionOrder.bind(this));
    }

    const matchedOrderDom:any = document.querySelector("#J_matchedOrder");
    this.renderOrder = R.curry((matchedOrderDom:any, order:any)=>{
      matchedOrderDom.firstElementChild.innerText = order&&order.serialNo||"";
      matchedOrderDom.lastElementChild.innerText = order&&(order.qty+"菜")||"";
    })(matchedOrderDom)


    const matchedEmployeeDom:any = document.querySelector("#J_matchedEmployee");
    this.renderEmployee = R.curry((matchedEmployeeDom:any, employee:any)=>{
      matchedEmployeeDom.innerText = employee&&employee.user&&employee.user.name || "";
    })(matchedEmployeeDom)
    
    // const YDOm = this.element.nativeElement.querySelector("#J_orderList");
    // Observable.fromEvent(YDOm,"click").subscribe(event=>{
    //         const serialNo = (<any>event).target.getAttribute("data-seriano");
    //   this.chooseDish({serialNo});
    // });

    const YDOm = this.element.nativeElement.querySelector("#J_orderList");
          YDOm.addEventListener("click", event=>{
                const serialNo = (<any>event).target.getAttribute("data-seriano");
                const id = (<any>event).target.getAttribute("data-id");
          this.chooseDish({serialNo,id});
        })  

    const elements:Array<any> = Array.from(this.element.nativeElement.querySelectorAll(".J_deliverySuccessed"));
    this.toggleDeliverySuccessed = ()=>{
        elements.forEach(ele=>{
            if(ele.style.display == "none"){
                ele.style.display = 'block';
            } else {
                ele.style.display = 'none';
            }
        })
    }

    this.subscriptions.push(this.selectOrders$.debounceTime(1000).subscribe(()=>{
         this.yScrollableContainers.last.childrenChanged();
    }))
  }
  dynamicWidth(i = 3) {
    let parent = this.el.nativeElement.querySelector('.delivery-list');
    let parentHeight = parent.clientHeight;
    let parentWidth = parent.clientWidth;
    let parentScrollHeight = parent.scrollHeight;
    let children = parent.children;
    if (parentScrollHeight > parentHeight) {
      parent.setAttribute('fxLayoutAlign', 'start space-around');
      Array.from(children).forEach(x => {
        (<any>x).style.width = (<any>((1 / (i + 1)) * 100)).toFixed(4) + '%';
        (<any>x).querySelector('.deliver').style.width = (<any>(1 / (i + 1))).toFixed(4) * parentWidth * .9 + 'px';
        (<any>x).querySelector('.deliver').style.height = (<any>(1 / (i + 1))).toFixed(4) * parentWidth * .9 + 'px';
      });
      this.dynamicWidth(i + 1);
    } else {
      parent.style.opacity = 1;
    }
  }

}

interface MatchDeliveryer {
  employee?: Employee
}